package com.googlecode.mad_schuelerturnier.business.print;

import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.html.simpleparser.HTMLWorker;
import com.lowagie.text.pdf.PdfWriter;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.PrettyXmlSerializer;
import org.htmlcleaner.TagNode;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.print.*;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.PrinterName;
import java.io.*;
import java.util.Collection;

/**
 * Created with IntelliJ IDEA.
 * User: dama
 * Date: 21.04.13
 * Time: 19:20
 * To change this template use File | Settings | File Templates.
 */

@Component
public class PrintAgent {

    private static final Logger LOG = Logger.getLogger(PrintAgent.class);

    private boolean running = false;

    private boolean init = false;

    private String pathprinter = "";
    private String pathdone = "";

    private String printer = "brother";

    public void init(String path){
        this.pathprinter = path  + "printer" + System.getProperty("file.separator");
        this.pathdone = path  + "printerdone" + System.getProperty("file.separator");
        new File(pathprinter).mkdirs();
        new File(pathdone).mkdirs();
        this.running = true;
        this.init = true;
    }

    public void printTestpage(){
        this.saveFileToPrint("testpage","this is the testpage");
        check();
    }
    
    public void printPage(String name, String content){
        this.saveFileToPrint(name,content);
        check();
    }

    @Scheduled(fixedDelay=15000)
    private void check(){

        if(!init){
            return;
        }

        Collection<File> files = FileUtils.listFiles(new File(pathprinter), null, false);
        for(File f : files){
            if(f.getName().contains(".xml")){
                 continue;
            }

            if(running){
                this.print(f);
            }

            try {
                FileUtils.copyFile(f,new File(this.pathdone + f.getName()));
            } catch (IOException e) {
                LOG.error(e.getMessage(),e);
            }
            FileUtils.deleteQuietly(f);
        }
    }

    public void saveFileToPrint(String name, String htmlContent){
        try {
        CleanerProperties props = new CleanerProperties();

         // set some properties to non-default values
        props.setTranslateSpecialEntities(true);
        props.setTransResCharsToNCR(true);
        props.setOmitComments(true);

        // do parsing
        TagNode tagNode = new HtmlCleaner(props).clean(
                htmlContent
        );

        Object[] o = tagNode.evaluateXPath("//body");

            // serialize to xml file
            new PrettyXmlSerializer(props).writeToFile(
                    (TagNode) o[0], pathprinter+"out.xml", "utf-8"
            );

            String outputFile = pathprinter+name+".pdf";
            OutputStream os = new FileOutputStream(outputFile);


            Document doc = new Document(PageSize.A4);
            PdfWriter.getInstance(doc, os);
            doc.open();
            HTMLWorker hw = new HTMLWorker(doc);
            hw.parse(new FileReader(pathprinter+"out.xml"));
            doc.close();
            os.close();

    } catch (Exception e) {
            LOG.error(e.getMessage(), e);
    }
        FileUtils.deleteQuietly(new File(pathprinter+"out.xml"));
    }

    private void print(File f) {

        FileInputStream in = null;

        try {
            in = new FileInputStream(f);
        } catch (FileNotFoundException e) {
           LOG.error(e.getMessage(),e);
        }
        DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;

        // find the printing service
        AttributeSet attributeSet = new HashAttributeSet();
        attributeSet.add(new PrinterName(printer, null));
        attributeSet.add(new Copies(1));

        PrintService service = PrintServiceLookup.lookupDefaultPrintService();

        //create document
        Doc doc = new SimpleDoc(in, flavor, null);

        DocPrintJob job = service.createPrintJob();

        LOG.info("PrintObserver: printing" + f.getName());

        try {
            job.print(doc, null);
        } catch (PrintException e) {
            LOG.error(e.getMessage(), e);
        }

        try {
            in.close();
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        }
    }

    public boolean isRunning(){
        return running;
    }

    public void setRunning(boolean running){
        this.running = running;
    }

    public String getPrinter() {
        return printer;
    }

    public void setPrinter(String printer) {
        this.printer = printer;
    }
}
